package com.devg.file.web.file.service.impl;

import com.devg.file.web.base.model.ResultModel;
import com.devg.file.web.base.utils.PageInfoUtils;
import com.devg.file.web.file.dao.FileMapper;
import com.devg.file.web.file.service.FileService;
import com.devg.file.web.utils.CommonUtil;
import com.devg.file.web.utils.LocalDateUtil;
import com.github.pagehelper.PageHelper;
import java.io.File;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service
public class FileServiceImpl implements FileService {

  public static final String fileSync = "FILE_SYNC";

  private static final Logger log = LoggerFactory.getLogger(FileServiceImpl.class);

  @Value("${rootPath}")
  private String rootPath;

  @Value("${netPath}")
  private String netPath;

  @Autowired
  private FileMapper fileMapper;


  @Override
  public Map<String, Object> baseUploadFile(MultipartFile file, String bucketName) throws Exception {
    return baseUploadFile(file, bucketName, false);
  }

  @Override
  public Map<String, Object> baseUploadFile(MultipartFile file, String bucketName, boolean isRandomFileName) throws Exception {
    String realFileName = file.getOriginalFilename();
    String fileName = file.getOriginalFilename();
    String fileType = fileName.substring(fileName.lastIndexOf("."));
    if (isRandomFileName) {
      fileName = UUID.randomUUID() + fileType;
    }
    // 文件存储路径
    String fileTargetPath = CommonUtil.changePath(rootPath) + bucketName;
    File dir = new File(fileTargetPath);
    if (!dir.exists()) {
      dir.mkdir();
    }
    String nowDate = LocalDateUtil.localDateFormat(LocalDate.now(), LocalDateUtil.FORMAT_PATTERN4);
    fileTargetPath = CommonUtil.changePath(fileTargetPath) + nowDate;
    File filePathDir = new File(fileTargetPath);
    if (!filePathDir.exists()) {
      filePathDir.mkdir();
    }
    File localFile = new File(CommonUtil.changePath(fileTargetPath) + fileName);
    file.transferTo(localFile);
    String filePath = bucketName + File.separator + nowDate + File.separator + fileName;
    Map<String, Object> result = new HashMap<>();
    result.put("bucketName", bucketName);
    result.put("fileName", fileName);
    result.put("fileType", fileType);
    result.put("filePath", filePath);
    result.put("netPath", CommonUtil.changePath(netPath) + filePath);
    result.put("realFileName", realFileName);
    result.put("fileSize", file.getSize());
    result.put("code", "200");
    result.put("message", "上传成功");
    int i = fileMapper.insertFile(result);
    if (i <= 0) {
      throw new Exception("上传数据错误");
    }
    log.info("上传文件:" + filePath + "成功!");
    return result;
  }

  @Override
  public Map<String, Object> uploadFileSync(MultipartFile file, String fileId, String filePath) throws Exception {
    Map<String, Object> result = new HashMap<>(3);
    String fileTargetPath = CommonUtil.changePath(rootPath) + filePath;
    fileTargetPath = fileTargetPath.replaceAll("//", "/");
    fileTargetPath = fileTargetPath.replaceAll("\\\\", "/");
    String fileDirPath = fileTargetPath.substring(0, fileTargetPath.lastIndexOf("/"));
    File filePathDir = new File(fileDirPath);
    if (!filePathDir.exists()) {
      filePathDir.mkdirs();
    }
    File localFile = new File(fileTargetPath);
    file.transferTo(localFile);
    result.put("code", "200");
    result.put("message", "同步成功");
    result.put("fileId", fileId);
    return result;
  }

  @Transactional
  @Override
  public Map<String, Object> deleteFile(String filePath) throws Exception {
    Map<String, Object> result = new HashMap<>(3);
    String fileTargetPath = CommonUtil.changePath(rootPath) + filePath;
    File file = new File(fileTargetPath);
    if (file.isFile() && file.exists()) {
      Map<String, Object> deleteMap = new HashMap<>(1);
      deleteMap.put("filePath", filePath);
      fileMapper.deleteFile(deleteMap);
      log.info("删除文件:" + fileTargetPath + "成功!");
      file.delete();
      result.put("code", "200");
      result.put("message", "刪除成功");
      result.put("filePath", filePath);
      return result;
    } else {
      result.put("code", "404");
      result.put("message", "文件不存在");
      result.put("filePath", filePath);
      log.info("删除文件:" + filePath + "失败,文件不存在!");
      return result;
    }
  }


  @Override
  public ResultModel list(Map<String, Object> params) {
    String startDate = CommonUtil.getMapString(params, "startDate");
    if (CommonUtil.isEmpty(startDate)) {
      startDate = LocalDateUtil.localDateFormat(LocalDate.now().minusDays(7), LocalDateUtil.FORMAT_PATTERN3);
    }
    String endDate = CommonUtil.getMapString(params, "endDate");
    if (CommonUtil.isEmpty(endDate)) {
      endDate = LocalDateUtil.localDateFormat(LocalDate.now(), LocalDateUtil.FORMAT_PATTERN3);
    }
    params.put("startTime", LocalDateUtil.getEarlyInTheDay(startDate));
    params.put("endTime", LocalDateUtil.getLastInTheDay(endDate));
    Integer pageNum = CommonUtil.getMapInteger(params, "page", 1);
    Integer pageSize = CommonUtil.getMapInteger(params, "limit", 10);
    PageHelper.startPage(pageNum, pageSize, true);
    List<Map<String, Object>> fileList = fileMapper.fileList(params);
    PageInfoUtils pageInfoUtils = new PageInfoUtils(fileList);
    return ResultModel.newSuccess(pageInfoUtils);
  }


  @Override
  public ResultModel syncConfigList(Map<String, Object> params) {
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put("syncConfigName", fileSync);
    List<Map<String, Object>> syncConfigList = fileMapper.getSyncConfigList(paramMap);
    return ResultModel.newSuccess(syncConfigList);
  }

  @Override
  public ResultModel syncConfigSet(Map<String, Object> params) {
    try {
      params.put("syncConfigName", fileSync);
      fileMapper.updateSyncConfig(params);
      return ResultModel.newSuccess();
    } catch (Exception ex) {
      log.error("syncConfigSet error", ex);
      return ResultModel.newFail();
    }
  }
}
